<template>
  <conf-module-container
    ref="refConfModuleContainer"
    class="role-form-page-container"
  >
    <template #Slot-Conf-Module-Header>
      <global-svg-icon
        icon-name="return"
        width="18px"
        height="18px"
        class="header-icon"
        style=""
        @click="router.go(-1)"
      ></global-svg-icon>
      <p class="font-20-bold" style="color: #f0f6fc">{{ cTitle }}</p>
    </template>

    <template #Slot-Conf-Module-Content>
      <div class="role-form-content">
        <a-form
          ref="formRef"
          class="_header"
          layout="horizontal"
          :model="formData"
        >
          <div class="font-14" style="color: #b0b5c0">角色名称</div>
          <a-form-item
            style="padding-bottom: 34px"
            label-align="left"
            name="roleName"
            :rules="[
              { required: true, message: '请输入角色名称', trigger: 'blur' },
            ]"
          >
            <a-input
              v-model:value.trim="formData.roleName"
              :disabled="editId === '1'"
              style="width: 320px; margin-top: 8px"
              :maxlength="10"
              placeholder="请输入"
            ></a-input>
          </a-form-item>
        </a-form>

        <div class="role-action-main">
          <div class="role-action-main-left">
            <p class="left-header font-14-bold">系统界面权限</p>
            <div class="left-container">
              <vue-scroll style="padding: 0 20px">
                <div class="role-form-menus">
                  <a-menu
                    :selected-keys="menuAttr.selectedKeys"
                    mode="inline"
                    :open-keys="menuAttr.openKeys"
                  >
                    <template :key="first.id" v-for="first in menuAttr.menus">
                      <template v-if="first.ext?.menuType === 'default-page'">
                        <a-menu-item
                          :key="first.id"
                          @click="setMenuItemClick(first.id)"
                        >
                          <div class="menu-node-item">
                            <span>{{ first.title }}</span>
                            <span class="nums">{{
                              cBtnSelectedNums(first.id)
                            }}</span>
                          </div>
                        </a-menu-item>
                      </template>

                      <template v-if="first.ext?.menuType === 'directory'">
                        <a-sub-menu :key="first.id">
                          <template #title>
                            <div class="menu-node-item">
                              <span>{{ first.title }}</span>
                            </div>
                          </template>

                          <template
                            :key="second.id"
                            v-for="second in first.childList"
                          >
                            <template
                              v-if="second.ext.menuType === 'default-page'"
                            >
                              <a-menu-item
                                :key="second.id"
                                @click="setMenuItemClick(second.id)"
                              >
                                <div class="menu-node-item">
                                  <span>{{ second.title }}</span>
                                  <span class="nums">{{
                                    cBtnSelectedNums(second.id)
                                  }}</span>
                                </div>
                              </a-menu-item>
                            </template>
                          </template>
                        </a-sub-menu>
                      </template>
                    </template>
                  </a-menu>
                </div>
              </vue-scroll>
            </div>

            <div class="left-footer">
              <a-button
                type="primary"
                :disabled="cDisableAllCheck"
                @click="setCheckAllMenus(true)"
                >全选</a-button
              >
              <a-button
                class="text-button"
                :disabled="editId === '1'"
                @click="setCheckAllMenus(false)"
                >清除</a-button
              >
            </div>
          </div>

          <div
            v-if="
              !!menuAttr.selectedKeys.length &&
              JSON.stringify(cSelectedMenu) !== '{}'
            "
            class="role-action-main-right"
          >
            <div class="role-form-checked">
              <div class="right-top">
                <p class="font-14-bold" style="flex: 1">
                  {{ cSelectedMenu.title }}
                </p>

                <a-checkbox
                  :checked="cMenuCheckBoxState.checked"
                  :indeterminate="cMenuCheckBoxState.indeterminate"
                  @change="(e: any) => setMenuItemCheck(e.target.checked)"
                ></a-checkbox>
              </div>

              <div class="right-body">
                <vue-scroll>
                  <div
                    v-if="cSelectedMenu.pageBtnList.length"
                    class="group"
                    :style="{
                      borderBottom:
                        cSelectedMenu.childList.length > 0
                          ? '1px solid rgba(211, 211, 211, 0.2)'
                          : 'none',
                    }"
                  >
                    <div
                      :key="btn.id"
                      v-for="btn in cSelectedMenu.pageBtnList"
                      class="btn-item"
                    >
                      <p class="btn-name-group">
                        <span>{{ btn.title }}</span>
                        <span
                          class="font-12"
                          style="font-weight: 400; color: #aaa"
                          >{{ ` (${btn.ext.remark})` }}</span
                        >
                      </p>
                      <!--:disabled="cDisabledBtnCheck(subBtn, cDisabledBtnCheck(btn, cSelectedMenu.ext.menuType)"  -->
                      <a-checkbox
                        :indeterminate="cSelected(btn, false)"
                        :checked="cSelected(btn, true)"
                        @change="
                          (e: any) => setButtonItemCheck(e.target.checked, btn)
                        "
                      ></a-checkbox>
                    </div>
                  </div>

                  <!-- 下层级的子页面 -->
                  <div v-if="cSelectedMenu.childList.length">
                    <div
                      :key="subMenu.id"
                      v-for="subMenu in cSelectedMenu.childList"
                    >
                      <div v-if="subMenu.pageBtnList.length > 1" class="group">
                        <div class="group-header">
                          <span class="font-14-bold">{{ subMenu.title }}</span>
                          <span
                            class="font-12"
                            style="font-weight: 400; color: #aaa"
                            >{{ `（子级菜单）` }}</span
                          >
                        </div>
                        <template v-if="subMenu.pageBtnList.length > 1">
                          <div
                            :key="subBtn.id"
                            v-for="subBtn in subMenu.pageBtnList"
                            class="btn-item"
                          >
                            <p class="btn-name-group">
                              <span>{{ subBtn.title }}</span>
                              <span
                                class="font-12"
                                style="font-weight: 400; color: #aaa"
                                >{{ ` (${subBtn.ext.remark})` }}</span
                              >
                            </p>
                            <!--:disabled="cDisabledBtnCheck(subBtn, subMenu.ext.menuType)"  -->
                            <a-checkbox
                              :checked="
                                menuAttr.checkedBtnIds.includes(subBtn.id)
                              "
                              @change="
                                (e: any) =>
                                  setButtonItemCheck(e.target.checked, subBtn)
                              "
                            ></a-checkbox>
                          </div>
                        </template>
                      </div>
                    </div>
                  </div>
                </vue-scroll>
              </div>
            </div>
          </div>
        </div>

        <div class="form-btns">
          <a-button type="primary" :disabled="editId === '1'" @click="saveForm"
            >确定</a-button
          >

          <a-button
            ghost
            style="margin-left: 8px"
            class="btn-default"
            @click="router.go(-1)"
            >取消</a-button
          >
        </div>
      </div>
    </template>
  </conf-module-container>

  <!-- 权限弹窗 -->
  <global-modal :open="modalIsOpen" :closable="false" :show-title="false">
    <div class="role-form-modal-content">
      <global-svg-icon
        icon-name="bule-warn"
        width="40px"
        height="40px"
        style="margin-bottom: 16px"
      ></global-svg-icon>
      <div>功能权限变更,账号即将推出</div>
      <div>请在退出后重新登录以查看最新权限</div>
      <span>(自动退出{{ countDown }}s后)</span>
    </div>
    <template #Slot-Footer>
      <div class="role-form-modal-btn">
        <a-button type="primary" @click="loginOut">确认退出</a-button>
      </div>
    </template>
  </global-modal>

  <!-- 权限弹窗 -->
  <global-modal :open="modalIsOpen" :closable="false" :show-title="false">
    <div class="role-form-modal-content">
      <global-svg-icon
        icon-name="bule-warn"
        width="40px"
        height="40px"
        style="margin-bottom: 16px"
      />
      <div>功能权限变更,账号即将推出</div>
      <div>请在退出后重新登录以查看最新权限</div>
      <span>(自动退出{{ countDown }}s后)</span>
    </div>
    <template #Slot-Footer>
      <div class="role-form-modal-btn">
        <a-button type="primary" @click="loginOut">确认退出</a-button>
      </div>
    </template>
  </global-modal>

  <teleport v-if="mountPage" to="body">
    <div class="shade-page">
      <a-spin size="large" tip="加载中..."></a-spin>
    </div>
  </teleport>
</template>

<script setup lang="ts" name="roles-form">
import { g6UseRoleForm } from "../../../hooks";
// import { g6UseRoleForm } from 'glasssix-vue3-hooks';
import { MenusAPI } from "@/global-services/api";
import { VerifyForm } from "@/global-utils/check";
import { TsRoleForm } from "../../../type";
import { ConfModuleContainer } from "../../../components/index";
import { RoleAPI } from "../../../api";

const {
  menuAttr,

  cSelectedMenu,

  cMenuCheckBoxState,

  cDisableAllCheck,

  cBtnSelectedNums,

  setMenuItemClick,

  setFormatMenus,

  setSelectedIds,

  setCheckAllMenus,

  setMenuItemCheck,

  setButtonItemCheck,
  cSelected,
} = g6UseRoleForm();

const $message: any = inject("$message");
const route = useRoute();
const router = useRouter();
const editId = ref(route.query.roleId as string);
const refConfModuleContainer = ref<any>(null);
const rolemainheight = ref("0px");
const cTitle = computed(() => (!route.query?.roleId ? "新增角色" : "编辑角色"));

const mountPage = ref(false);
const mountTip = ref("加载中...");
const loading = ref<boolean>(false);
const formRef = ref();
const formData = reactive<TsRoleForm>({ roleName: "", menuIds: [] });

const watchStop = watch(
  () => formData.roleName,
  () => {
    formData.roleName = formData.roleName.replace(/\s+/, "");
  }
);

const getRoleInfo = async () => {
  if (!editId.value) {
    return false;
  }
  try {
    formData.id = editId.value;
    const res: TsRes = await RoleAPI.detail(editId.value);
    if (res.code === 0) {
      formData.roleName = res.data.roleName;
      formData.menuIds = res.data.menuIds;
      setSelectedIds(res.data.menuIds);
    }
  } catch (error) {
    console.log(error);
  }
};

const getAllMenus = async () => {
  const res: TsRes = await MenusAPI.allMenus();
  if (res.code === 0) {
    setFormatMenus(res.data);
  }
};

// ========================权限弹窗========================
// 倒计时退出
const modalIsOpen = ref(false);
const countDown = ref(5);
const loginOut = () => {
  modalIsOpen.value = false;
  window.sessionStorage.clear();
  router.replace({ path: "/login" });
};
const modalCountDown = () => {
  modalIsOpen.value = true;
  let timer: NodeJS.Timeout | undefined;
  timer && clearInterval(timer);
  timer = setInterval(() => {
    countDown.value--;
    if (countDown.value <= 0) {
      clearInterval(timer);
      loginOut();
    }
  }, 1000) as NodeJS.Timeout;
};
// ========================权限弹窗 END========================
const saveForm = (): any => {
  formData.menuIds = [...menuAttr.checkedBtnIds, ...menuAttr.checkedMenuIds]; // 先清空
  VerifyForm(formRef, async () => {
    if (!formData.menuIds.length) {
      $message.warning("请选择当前角色所需的系统界面权限 !");
      return false;
    }
    loading.value = true;
    mountPage.value = true;
    mountTip.value = "保存中...";
    const newForm = JSON.parse(JSON.stringify(formData));
    try {
      let res: TsRes = !newForm.id
        ? await RoleAPI.add(newForm)
        : await RoleAPI.edit(newForm);
      if (res.code === 0) {
        const msgStr = !newForm.id ? "新增角色成功" : "编辑角色成功";
        $message.success(msgStr);
        if (newForm.id) {
          if (res.data === 1) {
            modalCountDown();
            return;
          }
        }
        router.go(-1);
      }
    } catch (error) {
      //
    } finally {
      loading.value = false;
      mountPage.value = false;
      mountTip.value = "加载中...";
    }
  });
};

onMounted(async () => {
  if (editId.value && editId.value === "1") {
    $message.warning("超级管理员角色无修改权限!");
  }

  mountPage.value = true;

  try {
    await getAllMenus();
    await getRoleInfo();
  } catch (error) {
    //
  } finally {
    let timer: any = setTimeout(() => {
      mountPage.value = false;
      clearTimeout(timer);
      timer = null;
    }, 700);
  }
  nextTick(() => {
    if (refConfModuleContainer.value) {
      rolemainheight.value =
        refConfModuleContainer.value.styleValue["--main-height"];
    }
  });
});

onUnmounted(() => {
  watchStop();
});
</script>

<style lang="less">
.role-form-page-container {
  --form-header-height: 96px;
  --form-btns-height: 76px;

  .__vuescroll {
    padding-top: 0 !important;
  }

  .header-icon {
    margin-right: 10px;
    vertical-align: middle;

    &:hover {
      opacity: 0.85;
      cursor: pointer;
    }
  }

  .role-form-content {
    display: flex;
    width: 840px;
    height: calc(v-bind(rolemainheight) - 40px);
    margin: 0 auto;
    border: 1px solid @borderColor02;
    border-radius: 4px;
    padding: 20px 20px 40px;
    flex-direction: column;
    background: @background02;
    box-shadow: 0 40px 180px 0 rgba(0, 0, 0, 0.35);

    ._header {
      height: var(--form-header-height);
    }

    .form-btns {
      height: var(--form-btns-height);
      padding-top: 40px;

      button {
        height: 36px !important;
      }
    }

    .role-action-main {
      display: flex;
      height: calc(100% - var(--form-header-height) - var(--form-btns-height));
      border: 1px solid @borderColor02;
      border-radius: 4px;
      background-color: #111e33;
      box-shadow: 0 40px 180px 0 rgba(0, 0, 0, 0.35);

      .role-action-main-left {
        width: 275px;
        height: 100%;
        border-right: 1px solid @borderColor02;
        padding: 16px 0;
        background: #101c30;

        .left-header {
          display: flex;
          align-items: center;
          height: 46px;
          padding: 0 20px 24px;
          color: @text01;
        }

        .left-container {
          height: calc(100% - 46px - 76px);
        }

        .left-footer {
          display: flex;
          align-items: center;
          height: 76px;
          margin-top: auto;
          padding: 40px 20px 0;

          .text-button {
            margin-left: 8px;
            border: none;
            font-size: 14px;
            font-weight: 400;
            font-style: normal;
            text-align: center;
            color: @text02;
            background: none;
          }
        }
      }

      .role-action-main-right {
        flex: 1;
        height: 100%;
      }
    }
  }

  .role-form-menus {
    width: 234px;

    .menu-node-item {
      display: flex;
      width: 100%;
      border-radius: 0 !important;
      padding: 5px 16px;
      color: @text02;
      align-items: center;
      justify-content: space-between;

      &:hover {
        border-radius: 0 !important;
        background-color: @mask04;
        cursor: pointer;
      }
    }

    .ant-menu {
      border: none;
      background-color: transparent !important;

      .ant-menu-item {
        width: 100%;
        height: 32px;
        padding: 0 16px 0 0 !important;
        line-height: 32px;

        &:hover {
          background-color: transparent !important;
          cursor: default;
        }

        &:active {
          background-color: transparent !important;
          cursor: default;
        }

        &::after {
          display: none;
        }
      }

      .ant-menu-submenu {
        &:hover {
          color: @text01 !important;
        }

        .ant-menu-submenu-title {
          position: relative;
          height: 32px;
          padding: 0 16px 0 0 !important;
          line-height: 32px;

          &:hover {
            color: @text01 !important;
            background-color: transparent !important;
            cursor: default;
          }

          &:active {
            background-color: transparent !important;
            cursor: default;
          }

          .ant-menu-submenu-arrow {
            left: 5px;
            color: @text01;
          }

          .sub-icon1 {
            position: absolute;
            left: 0;
            display: block;
            color: @text01;
          }

          .sub-icon2 {
            position: absolute;
            left: 0;
            display: none;
            color: @text01;
          }
        }

        .ant-menu-sub {
          margin-left: 20px !important;
          background-color: transparent !important;
        }
      }

      .ant-menu-item-selected {
        border-radius: 4px;
        background-color: transparent !important;

        .menu-node-item {
          color: @text01;
          background-color: @mask04;
        }
      }

      .ant-menu-submenu-selected {
        color: @text01;
      }
    }
  }

  .ant-menu-submenu-open {
    .ant-menu-submenu-title {
      .sub-icon1 {
        position: absolute;
        left: 0;
        display: none !important;
        color: @text01;
      }

      .sub-icon2 {
        position: absolute;
        left: 0;
        display: block !important;
        color: @text01;
      }
    }
  }

  .role-form-checked {
    height: 100%;
    // padding-bottom: 16px;

    .right-top {
      display: flex;
      height: 54px;
      padding: 20px;
      background-color: #0d172b;
      align-items: center;

      p {
        color: @text01;
      }
    }

    .right-body {
      height: calc(100% - 51px);
      background: #111e33;

      .group {
        // border-bottom: 1px solid rgba(211, 211, 211, 0.2);
        padding: 16px 16px 0;

        .btn-item {
          display: flex;
          min-height: 22px;
          margin: 0 0 16px 36px;
          border-radius: 4px;
          padding: 3px 3px 4px 0;
          font-size: 14px;
          font-weight: 400;
          line-height: 22px;
          color: rgba(0, 0, 0, 0.75);
          align-items: center;
          justify-content: space-between;

          .btn-name-group {
            color: @text01;
          }
        }

        .group-header {
          display: flex;
          height: 26px;
          margin-bottom: 12px;
          border-radius: 4px;
          padding: 2px 36px;
          line-height: 26px;
          color: @text01;
          background-color: @mask01;
          align-items: center;
          justify-content: flex-start;
        }
      }
    }
  }
}

.role-form-modal-content {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  color: #fff;

  span {
    color: @secondary01;
  }
}

.role-form-modal-btn {
  display: flex;
  justify-content: center;
}
</style>
